package com.yx.louti.login.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.yx.louti.globalException.model.BizAssert;
import com.yx.louti.globalException.model.BizException;
import com.yx.louti.interceptor.LoginInterceptor;
import com.yx.louti.login.enums.LoginType;
import com.yx.louti.login.model.LoginUserModel;
import com.yx.louti.web.bean.User;
import com.yx.louti.web.dao.UserDao;
import jtool.JString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 用户登陆服务
 */
@Service
public class LoginUserService {
    private static final Log log = LogFactory.get();
    @Autowired
    UserDao userDao;
    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 登陆
     * @param loginUserModel 登陆表单
     * @return 用户信息
     */
    public User checkAccountAndPassWord(LoginUserModel loginUserModel) {
        //先来一大堆检查
        BizAssert.notNull(loginUserModel,"登陆表单不能为空!");
        //登陆类型
        LoginType loginType = loginUserModel.getLoginType();
        BizAssert.notNull(loginType,"登陆类型不能为空!");
        //账号
        String account = loginUserModel.getAccount();
        BizAssert.notEmpty(account,"账号不能为空!");
        //密码
        String password = loginUserModel.getPassword();
        BizAssert.notEmpty(password,"密码不能为空!");

        User user = null;
        user = userDao.findByAccount(account);
        BizAssert.notNull(user, account + "账号不存在");
        BizAssert.isTrue(user.getAvailable(), "账号已冻结,请联系管理员");

        boolean passSure = user.getPassWord().equals(password);
        //定义一个redis的key
        String timesKey = "lt_login_error_times_" + user.getAccount();
        int times = JString.toInt(redisTemplate.opsForValue().get(timesKey));

        if (!passSure) {
            //密码错误计次
            if (times >= 5) {
                throw new BizException("密码错误次数过多,暂时冻结,请3分钟后再尝试");
            } else {
                times++;
                redisTemplate.opsForValue().set(timesKey, times + "", 3, TimeUnit.MINUTES);
                log.warn("账号:{} 第{}次密码错误", user.getAccount(), times);
                throw new BizException("密码错误");
            }
        }
        //如果账号密码一样的话  删除redis里面的用来计数错误次数的key
        if (times > 0) {
            redisTemplate.delete(timesKey);
        }
        //生成一个token，后面根据这个token来判断是否登陆
        String token = UUID.randomUUID().toString();
        //登陆成功,user的一些字段要更新
        user.setLastLoginTime(DateUtil.date());
        user.setErrorCount(0);
        user.setToken(token);
        User save = userDao.save(user);
        redisTemplate.opsForValue().set("lt_user_" + token, user.getId() + "", LoginInterceptor.token_valid_seconds, TimeUnit.SECONDS);
        return save;
    }



}
